﻿namespace Codeblack.TfsScrumboard.Repositories
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Codeblack.TfsScrumboard.Entities;
    using Codeblack.TfsScrumboard.Extensions;
    using Codeblack.TfsScrumboard.Interfaces;
    using Codeblack.TfsScrumboard.Resources;
    using Microsoft.TeamFoundation.WorkItemTracking.Client;

    public class TeamFoundationRepository : ITeamFoundationRepository
    {
        #region Constants

        private const string TeamProjectKey = "teamProject";
        private const string SprintTypeKey = "sprintType";
        private const string IterationPathKey = "iterationPath";

        #endregion

        #region Fields

        private IScrumboardSettings _scrumboardSettings = null;

        #endregion

        #region Constructor

        public TeamFoundationRepository(IScrumboardSettings scrumboardSettings)
        {
            _scrumboardSettings = scrumboardSettings;
        }

        #endregion

        #region ITeamFoundationRepository implementation

        public Backlog[] GetBacklogs(Project project)
        {
            Dictionary<string, string> queryValues = new Dictionary<string, string>();
            queryValues.Add(TeamProjectKey, project.Name);
            queryValues.Add(SprintTypeKey, this._scrumboardSettings.Sprints.SprintType);

            List<Backlog> backlogs = new List<Backlog>();
            backlogs.Add(new ProductBacklog(project));

            StringBuilder query = new StringBuilder();
            query.AppendFormat("SELECT {0} ", this._scrumboardSettings.Sprints.AllFieldNames);
            query.Append(" FROM WorkItems ");
            query.AppendFormat(" WHERE {0} = @{1} AND {2} = @{3} ", this._scrumboardSettings.Workitems.TeamProjectFieldName,
                                                                    TeamProjectKey,
                                                                    this._scrumboardSettings.Workitems.TypeFieldName,
                                                                    SprintTypeKey);
            query.AppendFormat(" ORDER BY {0}", this._scrumboardSettings.Sprints.StartDateFieldName);

            foreach (WorkItem sprint in project.Store.Query(query.ToString(), queryValues))
            {
                backlogs.Add(new SprintBacklog(project, sprint, this._scrumboardSettings));
            }

            return backlogs.ToArray();
        }

        public Workitem[] GetWorkitems(Project project, string iterationPath)
        {
            Dictionary<string, string> queryValues = new Dictionary<string, string>();
            queryValues.Add(TeamProjectKey, project.Name);
            queryValues.Add(IterationPathKey, iterationPath);

            StringBuilder query = new StringBuilder();
            query.AppendFormat("SELECT {0} ", this._scrumboardSettings.Workitems.AllFieldNames);
            query.Append(" FROM WorkItems ");
            query.AppendFormat(" WHERE {0} = @{1} AND {2} IN ({3}) ", this._scrumboardSettings.Workitems.TeamProjectFieldName,
                                                                    TeamProjectKey,
                                                                    this._scrumboardSettings.Workitems.TypeFieldName,
                                                                    this._scrumboardSettings.Workitems.WorkItemTypes);
            if (iterationPath == project.Name)
            {
                query.Append(" AND [System.IterationPath] UNDER @iterationPath ");
            }
            else
            {
                query.Append(" AND [System.IterationPath] = @iterationPath ");
            }
            query.Append(" ORDER BY ");
            query.Append(this._scrumboardSettings.Workitems.PriorityFieldName);

            List<Workitem> workItems = new List<Workitem>();

            foreach (WorkItem workItem in project.Store.Query(query.ToString(), queryValues))
            {
                workItems.Add(new Workitem(project, workItem, this._scrumboardSettings));
            }

            return workItems.ToArray();
        }

        public Workitem GetWorkitem(Project project, int id)
        {
            Dictionary<string, string> queryValues = new Dictionary<string, string>();
            queryValues.Add(TeamProjectKey, project.Name);

            StringBuilder query = new StringBuilder();
            query.AppendFormat("SELECT {0} ", this._scrumboardSettings.Workitems.AllFieldNames);
            query.Append(" FROM WorkItems ");
            query.AppendFormat(" WHERE {0} = {1} ", this._scrumboardSettings.Workitems.IDFieldName, id);

            Workitem workitem = null;

            WorkItemCollection workItems = project.Store.Query(query.ToString(), queryValues);
            if(workItems.Count > 0)
            {
                workitem = new Workitem(project, workItems[0], this._scrumboardSettings);
            }

            return workitem;
        }

        #endregion
    }
}
